﻿using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Data;
using FU.Capstones.IMS.Web.Common;
using FU.Capstones.IMS.Web.Common.InventoryServiceProxy.DataContracts;
using FU.Capstones.IMS.Web.Common.InventoryServiceProxy.EventArgs;
using FU.Capstones.IMS.Web.Silverlight.Models;
using FU.Capstones.IMS.Web.Silverlight.Popups;
using Microsoft.Practices.Prism.Commands;
using System.Linq;
using Navigation.Silverlight;

namespace FU.Capstones.IMS.Web.Silverlight.ViewModels
{
    public class MaterialListViewModel : ViewModelBase
    {
        public MaterialListViewModel()
        {
            Model = new MaterialListModel();
            ((MaterialListModel)Model).GetMaterialCollectionCompleted += DoGetMaterialCollectionCompleted;
            ((MaterialListModel)Model).SearhMaterialCompleted += DoSearhMaterialCompleted;
            ((MaterialListModel)Model).DeleteMaterialCompleted += DoDeleteMaterialCompleted;
            ((MaterialListModel)Model).UndoDeleteMaterialCompleted += UndoDeleteMaterialCompleted;
            ((MaterialListModel)Model).GetSingleMaterialCompleted += DoGetSingleMaterialCompleted;
            ((MaterialListModel) Model).GetPartnerCollectionCompleted += DoGetPartnerCollectionCompleted;
            ((MaterialListModel)Model).GetWarehouseCollectionCompleted += DoGetWarehouseCollectionCompleted;
            ((MaterialListModel)Model).GetMaterialCollectionTypeCompleted += DoGetMaterialCollectionTypeCompleted;

            MaterialCriteria = new MaterialCriteria();

            ServiceCallCounter += ((MaterialListModel)Model).GetMaterialCollectionAsync(IsShowAll);
            ServiceCallCounter += ((MaterialListModel)Model).GetMaterialCollectionTypeAsync(IsShowAll);
            ServiceCallCounter += ((MaterialListModel)Model).GetPartnerCollectionAsync();
            ServiceCallCounter += ((MaterialListModel) Model).GetWarehouseCollectionAsync();

            ErrorMessageVisibility = Visibility.Collapsed;
            MessageVisibility = Visibility.Collapsed;

            CanEditOrAdd = CurrentUser.CanEditMaterial;
            CanAdd = CurrentUser.CanAddMaterial;
        }

        #region Do Completed Methods

        void DoGetWarehouseCollectionCompleted(object sender, CollectionFeedbackCompletedEventArgs<Warehouse> e)
        {
            ServiceCallCounter -= WebConstants.MagicNumer;
            if (e.Error != null)
            {
                Message = e.Error.Message;
                SetMessageVisibility(false);
            }
            else
            {
                Message = e.Result.Message;
                SetMessageVisibility(e.Result.IsSuccessful);
                if (e.Result.IsSuccessful)
                {
                    WarehouseCollection = e.Result.Data;
                    WarehouseCollection.Insert(0, new Warehouse(){WarehouseID = 0, WarehouseName = "Tất cả"});
                }
            }
        }

        void DoGetPartnerCollectionCompleted(object sender, CollectionFeedbackCompletedEventArgs<Partner> e)
        {
            ServiceCallCounter -= WebConstants.MagicNumer;
            if (e.Error != null)
            {
                Message = e.Error.Message;
                SetMessageVisibility(false);
            }
            else
            {
                Message = e.Result.Message;
                SetMessageVisibility(e.Result.IsSuccessful);
                if (e.Result.IsSuccessful)
                {
                    SupplierCollection = e.Result.Data;
                }
            }
        }

        void DoGetSingleMaterialCompleted(object sender, SingleFeedbackCompletedEventArgs<Material> e)
        {
            ServiceCallCounter -= WebConstants.MagicNumer;
            if (e.Error != null)
            {
                Message = e.Error.Message;
                SetMessageVisibility(false);
            }
            else
            {
                Message = e.Result.Message;
                SetMessageVisibility(e.Result.IsSuccessful);
            }
        }

        void DoDeleteMaterialCompleted(object sender, FeedbackCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                Message = e.Error.Message;
                SetMessageVisibility(false);
            }
            else
            {
                Message = e.Result.Message;
                SetMessageVisibility(e.Result.IsSuccessful);
                if (e.Result.IsSuccessful)
                {
                    ServiceCallCounter += ((MaterialListModel)Model).GetMaterialCollectionTypeAsync(IsShowAll);
                }
            }
            ServiceCallCounter -= WebConstants.MagicNumer;
        }

        void UndoDeleteMaterialCompleted(object sender, FeedbackCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                Message = e.Error.Message;
                SetMessageVisibility(false);
            }
            else
            {
                Message = e.Result.Message;
                SetMessageVisibility(e.Result.IsSuccessful);
                if (e.Result.IsSuccessful)
                {
                    NavigationManager.NavigateTo(WebConstants.NavigationPages.MaterialDetail, currentMaterialID);
                }
            }
            ServiceCallCounter -= WebConstants.MagicNumer;
        }

        void DoSearhMaterialCompleted(object sender, CollectionFeedbackCompletedEventArgs<Material> e)
        {
            ServiceCallCounter -= WebConstants.MagicNumer;
            if (e.Error != null)
            {
                Message = e.Error.Message;
                SetMessageVisibility(false);
            }
            else
            {
                Message = e.Result.Message;
                SetMessageVisibility(e.Result.IsSuccessful);
                if (e.Result.IsSuccessful)
                {
                    ErrorMessageVisibility = Visibility.Collapsed;
                    MessageVisibility = Visibility.Visible;
                    MaterialCollection = new PagedCollectionView(e.Result.Data);
                }
            }
        }

        void DoGetMaterialCollectionCompleted(object sender, CollectionFeedbackCompletedEventArgs<Material> e)
        {
            ServiceCallCounter -= WebConstants.MagicNumer;
            if (e.Error != null)
            {
                Message = e.Error.Message;
                SetMessageVisibility(false);
            }
            else
            {
                Message = e.Result.Message;
                SetMessageVisibility(e.Result.IsSuccessful);
                if (e.Result.IsSuccessful)
                {
                    MaterialCollection = new PagedCollectionView(e.Result.Data);
                }
            }
        }

        void DoGetMaterialCollectionTypeCompleted(object sender, CollectionFeedbackCompletedEventArgs<Material> e)
        {
            ServiceCallCounter -= WebConstants.MagicNumer;
            if (e.Error != null)
            {
                Message = e.Error.Message;
                SetMessageVisibility(false);
            }
            else
            {
                Message = e.Result.Message;
                SetMessageVisibility(e.Result.IsSuccessful);
                if (e.Result.IsSuccessful)
                {
                    MaterialTypeCollection = new PagedCollectionView(e.Result.Data);
                }
            }
        }

        #endregion

        #region Commands

        #region ViewCommand

        private DelegateCommand<int?> viewCommand;
        public DelegateCommand<int?> ViewCommand
        {
            get
            {
                if (viewCommand == null)
                {
                    viewCommand = new DelegateCommand<int?>(DoViewCommand);
                }
                return viewCommand;
            }
        }

        private void DoViewCommand(int? obj)
        {
            if (obj.HasValue)
                ServiceCallCounter += ((MaterialListModel)Model).GetSingleMaterialAsync(obj.Value);
        }

        #endregion

        #region ShowAllCommand

        private DelegateCommand<object> showAllCommand;
        public DelegateCommand<object> ShowAllCommand
        {
            get
            {
                if (showAllCommand == null)
                {
                    showAllCommand = new DelegateCommand<object>(DoShowAllCommand);
                }
                return showAllCommand;
            }
        }

        private void DoShowAllCommand(object obj)
        {
            //ServiceCallCounter +=((MaterialListModel)Model).GetMaterialCollectionAsync(IsShowAll);
            ServiceCallCounter +=
               ((MaterialListModel)Model).GetMaterialCollectionTypeAsync(IsShowAll);

        }

        #endregion

        #region EditCommand

        private DelegateCommand<int?> editCommand;
        public DelegateCommand<int?> EditCommand
        {
            get
            {
                if (editCommand == null)
                {
                    editCommand = new DelegateCommand<int?>(DoEditCommand);
                }
                return editCommand;
            }
        }

        private void DoEditCommand(int? obj)
        {
            if(obj.HasValue)
            {
                currentMaterialID = obj.Value;
                
                var temp = MaterialCollection.Cast<Material>().FirstOrDefault(x => x.MaterialID == currentMaterialID);
                
                if (temp.IsDelete )
                {
                    var popup = new UndoDeleteConfirmationPopup();
                    popup.Show();
                    popup.Closed += (sender, e) =>
                                        {
                                            if (popup.DialogResult.HasValue && popup.DialogResult.Value)
                                            {
                                                ServiceCallCounter += ((MaterialListModel)Model).UndoDeleteMaterialAsync(currentMaterialID);
                                                
                                            }
                                        };
                }
                else
                {
                    NavigationManager.NavigateTo(WebConstants.NavigationPages.MaterialDetail, currentMaterialID);
                    
                }

                
                
            }
        }

        private DelegateCommand<int?> editCommand2;
        public DelegateCommand<int?> EditCommand2
        {
            get
            {
                if (editCommand2 == null)
                {
                    editCommand2 = new DelegateCommand<int?>(DoEditCommand2);
                }
                return editCommand2;
            }
        }

        private void DoEditCommand2(int? obj)
        {
            if (obj.HasValue)
            {
                currentMaterialID = obj.Value;

                var temp = MaterialTypeCollection.Cast<Material>().FirstOrDefault(x => x.MaterialID == currentMaterialID);

                if (temp.IsDelete)
                {
                    var popup = new UndoDeleteConfirmationPopup();
                    popup.Show();
                    popup.Closed += (sender, e) =>
                    {
                        if (popup.DialogResult.HasValue && popup.DialogResult.Value)
                        {
                            ServiceCallCounter += ((MaterialListModel)Model).UndoDeleteMaterialAsync(currentMaterialID);

                        }
                    };
                }
                else
                {
                    NavigationManager.NavigateTo(WebConstants.NavigationPages.MaterialDetail, currentMaterialID);

                }



            }
        }

        #endregion
        
        #region DeleteCommand

        private DelegateCommand<int?> deleteCommand;
        public DelegateCommand<int?> DeleteCommand
        {
            get
            {
                if (deleteCommand == null)
                {
                    deleteCommand = new DelegateCommand<int?>(DoDeleteCommand);
                }
                return deleteCommand;
            }
        }

        private void DoDeleteCommand(int? obj)
        {
            if (obj.HasValue)
            {
                var popup = new DeleteConfirmationPopup();
                popup.Show();
                popup.Closed += (sender, e) =>
                                    {
                                        if (popup.DialogResult.HasValue && popup.DialogResult.Value)
                                        {
                                            ServiceCallCounter +=
                                                ((MaterialListModel) Model).DeleteMaterialAsync(obj.Value);
                                        }
                                    };
            }

            
        }

        #endregion

        #region CreateCommand

        private DelegateCommand<object > createCommand;
        public DelegateCommand<object> CreateCommand
        {
            get
            {
                if (createCommand == null)
                {
                    createCommand = new DelegateCommand<object>(DoCreateCommand);
                }
                return createCommand;
            }
        }

        private void DoCreateCommand(object obj)
        {
            NavigationManager.NavigateTo(WebConstants.NavigationPages.MaterialDetail);
        }

        #endregion

        #region SearchCommand

        private DelegateCommand<object> searchCommand;
        public DelegateCommand<object> SearchCommand
        {
            get
            {
                if (searchCommand == null)
                {
                    searchCommand = new DelegateCommand<object>(DoSearchCommand);
                }
                return searchCommand;
            }
        }

        private void DoSearchCommand(object obj)
        {
            if (MaterialCriteria.SelectedWarehouse != null && MaterialCriteria.SelectedWarehouse.WarehouseID != 0)
            {
                if (MaterialCriteria.WarehouseIDCollection == null)
                {
                    MaterialCriteria.WarehouseIDCollection = new ObservableCollection<int>();
                }
                else
                {
                    MaterialCriteria.WarehouseIDCollection.Clear();
                }
                MaterialCriteria.WarehouseIDCollection.Add(MaterialCriteria.SelectedWarehouse.WarehouseID);
            }
            else
            {
                MaterialCriteria.WarehouseIDCollection = new ObservableCollection<int>();
            }

            ServiceCallCounter += ((MaterialListModel)Model).SearchMaterialAsync(MaterialCriteria);
            Message = WebConstants.SearchingMessage;
        }

        #endregion
        
        #endregion
        
        #region Binding Properties

        private PagedCollectionView materialCollection;
        public PagedCollectionView MaterialCollection
        {
            get { return materialCollection; }
            set
            {
                if (!ReferenceEquals(materialCollection, value))
                {
                    materialCollection = value;
                    RaisePropertyChanged(() => MaterialCollection);
                }
            }
        }

        private PagedCollectionView materialTypeCollection;
        public PagedCollectionView MaterialTypeCollection
        {
            get { return materialTypeCollection; }
            set
            {
                if (!ReferenceEquals(materialTypeCollection, value))
                {
                    materialTypeCollection = value;
                    RaisePropertyChanged(() => MaterialTypeCollection);
                }
            }
        }

        private ObservableCollection<Warehouse> warehouseCollection;
        public ObservableCollection<Warehouse> WarehouseCollection
        {
            get { return warehouseCollection; }
            set
            {
                if(!ReferenceEquals(warehouseCollection, value))
                {
                    warehouseCollection = value;
                    RaisePropertyChanged(() => WarehouseCollection);
                }
            }
        }

        private ObservableCollection<Partner> supplierCollection;
        public ObservableCollection<Partner> SupplierCollection
        {
            get { return supplierCollection; }
            set
            {
                if(!ReferenceEquals(supplierCollection, value))
                {
                    supplierCollection = value;
                    RaisePropertyChanged(() => SupplierCollection);
                }
            }
        }

        private MaterialCriteria materialCriteria;
        public MaterialCriteria MaterialCriteria
        {
            get { return materialCriteria; }
            set
            {
                if (!ReferenceEquals(materialCriteria, value))
                {
                    materialCriteria = value;
                    RaisePropertyChanged(() => MaterialCriteria);
                }
            }
        }

        #endregion

        #region Fields

        private int currentMaterialID = 0;
        
       
        #endregion

        #region Implementation of INavigationAware

        public override void OnNavigate(object extraData)
        {
            //((MaterialListModel)model).GetMaterialCollectionAsync();
        }

        public override void OnLeave()
        {
            //throw new NotImplementedException();
        }

        #endregion

        protected override void HandleLoadingCompleted()
        {
            
        }
    }
}
